﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using APC.Common; //Database Handling


namespace APC
{
    class Batch
    {

        #region Declarations

        private List<APC.Common.BatchListe> BatchList; //Holds full TagName list to avoid reload on multiple runs (cache)
        private DataHandlingDataContext ctx;

        #endregion

        #region Constructor

        public Batch()
        {
        }


        #endregion

        #region Properties

        public string BatchNumber
        {
          get { return this._BatchNumber; }
          set { this._BatchNumber = value; }
        }       
        private string _BatchNumber = "";

        public int OrderId
        {
            get { return this._OrderId; }
            set { this._OrderId = value; }
        }
        private int _OrderId = 0;

        public int BacthCountNumber
        {
            get { return this._BacthCountNumber; }
            set { this._BacthCountNumber = value; }
        }
        private int _BacthCountNumber = 0;

        public int PacketSize
        {
            get { return this._PacketSize; }
            set { this._PacketSize = value; }
        }
        private int _PacketSize = 0;

        public int TagListeGroupId
        {
            get { return this._TagListeGroupId; }
            set { this._TagListeGroupId = value; }
        }
        private int _TagListeGroupId = 0;

        public int ZenonControlId
        {
            get { return this._ZenonControlId; }
            set { this._ZenonControlId = value; }
        }
        private int _ZenonControlId = 0;

        public int SendToZenon
        {
            get { return this._SendToZenon; }
            set { this._SendToZenon = value; }
        }
        private int _SendToZenon = 0;

        public int Status
        {
            get { return this._Status; }
            set { this._Status = value; }
        }
        private int _Status = 0;

        /// <summary>
        /// Holds all Tags and there values for a location like Scale 1, Silo 1
        /// </summary>
        public List<TagValuePair> TagValuePairs
        {
            get { return this._TagValuePairs; }
            set { this._TagValuePairs = value; }
        }
        private List<TagValuePair> _TagValuePairs = null;

        /// <summary>
        /// Holds all Tags and there values for a location like Scale 1, Silo 1
        /// </summary>
        public List<LiveBatch> LiveBatchList
        {
            get { return this._LiveBatchList; }
            set { this._LiveBatchList = value; }
        }
        private List<LiveBatch> _LiveBatchList = null;

        #endregion

        #region Methods

        /// <summary>
        /// Show live data for running order
        /// </summary>
        /// <returns></returns>
        public List<LiveBatch> ListRunningOrderBatchList()
        {
            if (ctx == null)
            {
                ctx = new DataHandlingDataContext(new Data().ConnectionString);
            }

            var order = (from o in ctx.Orders
                         from r in ctx.Recipes
                         where o.RecipeId == r.Id
                         select new
                         { 
                             OrderId = o.Id, 
                             RecipeName = r.RecipeName 
                         });

            var batchinprocess = (from ba in ctx.BatchListes
                                  where ba.Status > 0
                                  group ba by new 
                                  { 
                                      ba.OrderId, 
                                      ba.TagListGroupId 
                                  }
                                      into grp
                                      select new 
                                      { 
                                          OrderId = grp.Key.OrderId 
                                      });

            var batch = (from b in ctx.BatchListes
                         from bip in batchinprocess
                         where b.OrderId == bip.OrderId
                         group b by new 
                         { 
                             b.OrderId, 
                             b.BatchCountNo, 
                             b.OrderSequence, 
                             b.Status 
                         } //group b by new {b.OrderId, b.BatchCountNo, b.Status, b.OrderSequence}
                         into grp
                         select new
                         {
                            OrderId = grp.Key.OrderId,
                            //TagListGroupId = grp.Key.TagListGroupId,
                            BatchCountNumber = grp.Key.BatchCountNo,
                            Status = grp.Key.Status,
                            OrderSequence = grp.Key.OrderSequence
                         }).OrderByDescending(x => x.BatchCountNumber)
                           .OrderByDescending(x => x.OrderSequence)                          
                           .OrderBy(x => x.OrderId)
                           .Select(x => new LiveBatch()
                             {
                                 BatchCountNumber = Convert.ToInt32(x.BatchCountNumber),
                                 Status = x.Status,
                                 OrderId = x.OrderId,
                                 //TagListGroupId = x.TagListGroupId,
                                 OrderSequence = (int)x.OrderSequence,
                                 RecipeName = (string)(from o in order 
                                                       where o.OrderId == x.OrderId 
                                                       select o.RecipeName).FirstOrDefault()
                                             
                             }).ToList();
      
            return batch;
        }


        public void RemoveOrderFromBatchListe()
        {
            if (ctx == null)
            {
                ctx = new DataHandlingDataContext(new Data().ConnectionString);
            }
                ctx.ExecuteCommand("DELETE FROM BatchListe WHERE OrderId = " + _OrderId);
        }

        public void UpdateOrderSequence()
        {

            if (ctx == null)
            {
                ctx = new DataHandlingDataContext(new Data().ConnectionString);
            }

            var orders = (from o in ctx.Orders
                          select o);

            foreach (var order in orders)
            {
                ctx.ExecuteCommand("UPDATE BatchListe SET OrderSequence = " + order.OrderSequence + " WHERE OrderId = " + order.Id);
            }
        }


        /// <summary>
        /// Adds a batch list item to db table "BatchList"
        /// </summary>
        /// <param name="BatchListeItem"></param>
        public void SaveItem(APC.Common.BatchListe BatchListeItem)
        {
            if (ctx == null)
            {
                ctx = new DataHandlingDataContext(new Data().ConnectionString);
            }

            ctx.BatchListes.InsertOnSubmit(BatchListeItem);
            ctx.SubmitChanges();
        }

        #endregion
    }

    /// <summary>
    /// Holds infor about pending/running orders
    /// </summary>
    public class LiveBatch
    {

        public int OrderId
        {
            get { return this._OrderId; }
            set { this._OrderId = value; }
        }
        private int _OrderId = 0;

        public int TagListGroupId
        {
            get { return this._TagListGroupId; }
            set { this._TagListGroupId = value; }
        }
        private int _TagListGroupId = 0;

        public string BacthNumber
        {
            get { return this._BatchNumber; }
            set { this._BatchNumber = value; }
        }
        private string _BatchNumber = "";

        public int BatchCountNumber
        {
            get { return this._BatchCountNumber; }
            set { this._BatchCountNumber = value; }
        }
        private int _BatchCountNumber = 0;

        public int Status
        {
            get { return this._Status; }
            set { this._Status = value; }
        }
        private int _Status = 0;

        public int OrderSequence
        {
            get { return this._OrderSequence; }
            set { this._OrderSequence = value; }
        }
        private int _OrderSequence = 0;

        public string RecipeName
        {
            get { return this._RecipeName; }
            set { this._RecipeName = value; }
        }
        private string _RecipeName = "";

    }
}
